//geneticalgorithmsteps.h

//This will randomly create a world of candidate (possible) solutions.
void populate()
{
	int i,j;
        vector <int> candidate;
        for( i = 0 ; i < POPULATION_SIZE ; i++ )
          {
            for(j = 1; j <=  gNetwork.size(); j++) 
              candidate.push_back(j);
            random_shuffle( candidate.begin() , candidate.end());
            gCurrentGeneration.push_back( candidate );
            candidate.clear();
          }
}

//used as an argument for sorting
bool myDataSortPredicate( vector<int> candidate1 , vector<int> candidate2)
{
	return (fitness(candidate1) < fitness(candidate2));
}
 
void selection ()
{
        vector<int> candidate;
        // Sort the vector using predicate 
        sort(gCurrentGeneration.begin(), gCurrentGeneration.end(), myDataSortPredicate);
        gSolution = gCurrentGeneration[0];//current best solution
        //remove some solutions which are not fit
        gCurrentGeneration.resize(GROUP_SIZE);
} 	


void mutation ()
{
	int mutationsite1,mutationsite2,i,sizeOfCandidate,numberOfMutatedCandidates;
        vector < int > candidate;
        
        //initialize random seed
        srand(time(NULL));
        
        sizeOfCandidate = gNetwork.size();
        numberOfMutatedCandidates = (gCurrentGeneration.size() * MUTATION_RATE)/100;
   
        random_shuffle(gCurrentGeneration.begin(),gCurrentGeneration.end());
        for( i = 0; i < numberOfMutatedCandidates ; i++)
          {
            candidate = gCurrentGeneration[i];
	    mutationsite1 = rand() % sizeOfCandidate;
            mutationsite2 = rand() % sizeOfCandidate;
            swap(candidate[mutationsite1],candidate[mutationsite2]);
            gCurrentGeneration.push_back(candidate);
          }
}

double fitness( vector< int > candidate)
{
  double fitnes = 0,underRoot = 0,x1,x2,y1,y2;
  int i;
  for( i = 0 ; i < candidate.size()-1; i++)
      {
               x1 = gNetwork[candidate[i]-1].X();
               x2 = gNetwork[candidate[i+1]-1].X();
               y1 = gNetwork[candidate[i]-1].Y();
               y2 = gNetwork[candidate[i+1]-1].Y();
               underRoot = ( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) );
               fitnes += sqrt( underRoot ) + ADDITIONAL_FEET;

      }
  return fitnes;  	
}

